﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Windows.Forms;
using System.Xml;

namespace DataProcess {
	public partial class frmXmlToAccess : Form {

		public static int identity = 1;

		public frmXmlToAccess() {
			InitializeComponent();
			folderBrowserDialog1.SelectedPath = System.Windows.Forms.Application.StartupPath;
			openFileDialog1.InitialDirectory = System.Windows.Forms.Application.StartupPath;
		}

		private void button3_Click(object sender, EventArgs e) {
			uptodateDataSetTableAdapters.articleTableAdapter adp = new uptodateDataSetTableAdapters.articleTableAdapter();
			var conn = adp.Connection;
			if (conn.State != ConnectionState.Open) {
				conn.Open();
			}
			if (!Directory.Exists(textBox2.Text)) {
				MessageBox.Show("xml路径不存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			backgroundWorker1.RunWorkerAsync(new string[] { textBox1.Text, textBox2.Text });

		}

		private void button1_Click(object sender, EventArgs e) {
			if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
				textBox1.Text = openFileDialog1.FileName;
			}
		}

		private void button2_Click(object sender, EventArgs e) {
			if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
				textBox2.Text = folderBrowserDialog1.SelectedPath;
			}
		}

		private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
			var bw = sender as BackgroundWorker;
			string[] args = (string[])e.Argument;
			string xmlDir = args[1];
			string[] articles = null, xmlFiles = null;
			if (!string.IsNullOrEmpty(args[0])) {
				articles = File.ReadAllLines(args[0]);
			}
			else {
				xmlFiles = Directory.GetFiles(xmlDir, "*.xml", SearchOption.AllDirectories);
			}
			uptodateDataSetTableAdapters.articleTableAdapter adp = new uptodateDataSetTableAdapters.articleTableAdapter();

			var uptodate = adp.GetData();
			if (articles != null && articles.Length > 0) {
				string artid = string.Empty, title = string.Empty;
				for (int i = 0; i < articles.Length; i++) {
					if (articles[i].IndexOf('\t') > -1) {
						string[] cts = articles[i].Split('\t');
						artid = cts[0];
						title = cts[1];
					}
					else if (Path.GetExtension(articles[i]) == ".xml" && !string.IsNullOrEmpty(artid) && !string.IsNullOrEmpty(title)) {
						string xmlFilePath = Path.Combine(xmlDir, articles[i]);
						AddXmlFile(uptodate, artid, title, xmlFilePath);
					}
					int Percentage = (int)(((double)(i + 1) / (double)articles.Length) * 100);
					bw.ReportProgress(Percentage, "读取xml");
				}
			}
			if (xmlFiles != null && xmlFiles.Length > 0) {
				for (int i = 0; i < xmlFiles.Length; i++) {
					AddXmlFile(uptodate, string.Empty, string.Empty, xmlFiles[i]);
					int Percentage = (int)(((double)(i + 1) / (double)xmlFiles.Length) * 100);
					bw.ReportProgress(Percentage, "读取xml");
				}
			}
			bw.ReportProgress(0, "正在更新数据");
			adp.Update(uptodate);
			var cmd = adp.Connection.CreateCommand();
			if (cmd.Connection.State != ConnectionState.Open) {
				cmd.Connection.Open();
			}
			cmd.CommandText = "INSERT INTO keywords ( KeyId, Canonicals) SELECT article.node_id, Count(article.node_id) FROM article GROUP BY article.node_id HAVING article.node_id<>''";
			cmd.ExecuteNonQuery();
			cmd.CommandText = "UPDATE keywords INNER JOIN article ON keywords.KeyId = article.node_id SET keywords.KeyName = [article].[node_value], keywords.NameType = [article].[node_name], keywords.Canonical = [article].[CanonicalKeywordId]";
			cmd.ExecuteNonQuery();
			cmd.CommandText = "INSERT INTO [keywords] ( KeyId, KeyName, NameType ) SELECT DISTINCT article.CanonicalKeywordId, article.CanonicalName, 'Canonical' FROM article WHERE not Exists (select [keywords].keyid from keywords where [keywords].keyid= article.CanonicalKeywordId)";
			cmd.ExecuteNonQuery();
			cmd.Connection.Dispose();
			cmd.Dispose();
		}

		/// <summary>
		/// 蒋单条xml的数据插入到table中
		/// </summary>
		/// <param name="uptodate"></param>
		/// <param name="artid"></param>
		/// <param name="title"></param>
		/// <param name="xmlFilePath"></param>
		private static void AddXmlFile(uptodateDataSet.articleDataTable uptodate, string artid, string title, string xmlFilePath) {
			var fileData = GetSingleXml(xmlFilePath);
			if (fileData != null) {
				for (int j = 0; j < fileData.Nodes.Length; j++) {
					uptodate.Rows.Add(identity, artid, title, Path.GetFileName(xmlFilePath), fileData.CanonicalKeywordId, fileData.CanonicalName, fileData.Nodes[j].Name, fileData.Nodes[j].Id, fileData.Nodes[j].Value);
					identity++;
				}
				if (fileData.Nodes.Length == 0) {
					uptodate.Rows.Add(identity, artid, title, Path.GetFileName(xmlFilePath), fileData.CanonicalKeywordId, fileData.CanonicalName, string.Empty, string.Empty, string.Empty);
					identity++;
				}

			}
		}

		/// <summary>
		/// 读取单条xml文件数据
		/// </summary>
		/// <param name="articles"></param>
		/// <param name="artid"></param>
		/// <param name="title"></param>
		/// <param name="adp"></param>
		/// <param name="i"></param>
		/// <param name="xmlFilePath"></param>
		private static xmlFile GetSingleXml(string xmlFilePath) {
			xmlFile file = null;
			if (File.Exists(xmlFilePath)) {
				XmlDocument doc = new XmlDocument();
				doc.Load(xmlFilePath);
				XmlNode root = doc.DocumentElement;
				var node = root.SelectSingleNode("Canonical");
				file = new xmlFile();
				file.CanonicalKeywordId = node.Attributes["CanonicalKeywordId"].Value;
				file.CanonicalName = node.Attributes["CanonicalName"].Value;

				var children = node.ChildNodes;
				file.Nodes = new xmlNode[children.Count];
				for (int j = 0; j < children.Count; j++) {
					file.Nodes[j] = new xmlNode { Name = children[j].Name, Id = children[j].Attributes[0].Value, Value = children[j].Attributes[1].Value };
				}
			}
			return file;
		}

		private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
			progressBar1.Value = e.ProgressPercentage;
			if (e.UserState != null) {
				label3.Text = string.Format("进度：{0}", e.UserState);
			}
		}

		private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
			MessageBox.Show("完成");
		}

		private void button4_Click(object sender, EventArgs e) {
			uptodateDataSetTableAdapters.keywordsTableAdapter keyadp = new uptodateDataSetTableAdapters.keywordsTableAdapter();
			uptodateDataSetTableAdapters.articleTableAdapter articleadp = new uptodateDataSetTableAdapters.articleTableAdapter();
			var artiCmd = articleadp.Connection.CreateCommand();
			if (artiCmd.Connection.State != ConnectionState.Open) {
				artiCmd.Connection.Open();
			}
			var data = keyadp.GetData();
			for (int i = 0; i < data.Count; i++) {
				if (data[i].NameType == "Canonical" || data[i].Canonicals == 1) {
					continue;
				}
				artiCmd.CommandText = string.Format("SELECT article.CanonicalKeywordId FROM article WHERE article.[node_id]='{0}'", data[i].KeyId);
				List<string> ids = new List<string>();
				var reader = artiCmd.ExecuteReader();
				while (reader.Read()) {
					ids.Add(reader[0].ToString());
				}
				reader.Close();
				if (ids.Count > 0) {
					data[i].Canonical = string.Join<string>(",", ids);
				}
			}
			artiCmd.Connection.Dispose();
			artiCmd.Dispose();
			keyadp.Update(data);
			MessageBox.Show("处理完成！");
		}
	}
	class xmlFile {
		public string CanonicalKeywordId { get; set; }
		public string CanonicalName { get; set; }
		public xmlNode[] Nodes { get; set; }
	}
	class xmlNode {
		public string Name { get; set; }
		public string Id { get; set; }
		public string Value { get; set; }
	}
}
